package service

import (
	"errors"
	"strconv"
	"time"
	"web_framework/model"
	"web_framework/pkg/constvar"
	. "web_framework/pkg/e"
	"web_framework/storage"
	"web_framework/pkg/e"
)

func CyclicCheckTaskStatus(sn string, taskId int64, FailStatus int, exceptStatus int) error {
	taskIdStr := strconv.FormatInt(taskId, 10)
	taskInfoCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskInfoKey + ":" + taskIdStr
	for a := 1; a <= 6; a++ {
		Log("Info", "循环到第", a, "次")
		time.Sleep(time.Duration(10) * time.Second)
		taskStatus, getInfoErr := storage.RedisHGet(taskInfoCacheKey, "status")
		if getInfoErr != nil {
			Log("Info", "获取reids失败", "cyclicCheckTaskStatus:查询任务详情缓存失败")
			return errors.New("cyclicCheckTaskStatus:查询任务详情缓存失败")
		}
		intStatus, _ := strconv.Atoi(taskStatus)
		//任务状态已修改未期待中的状态，则停止轮询
		if intStatus == exceptStatus {
			return nil
		} else if intStatus == model.TaskStatusLoadFail {
			break
		}
	}
	//3次轮询，任务状态始终没变，则默认任务处理失败
	if err := UpdateQueueTaskStatus(taskId, sn, FailStatus); err != nil {
		Log("Info", "cyclicCheckTaskStatus:修改任务状态失败")
		return errors.New("cyclicCheckTaskStatus:修改任务状态失败")
	}
	Log("Info", "任务处理失败")

	return errors.New("cyclicCheckTaskStatus:任务处理失败")
}

//移除未完成队列中的任务
func DelLoadTask(taskID int64, sn string, taskStatus int) error {
	//根据当前任务状态，移除对应任务队列（暂停、下载中）中的任务
	if taskStatus == model.TaskStatusWaiting {
		if err := DelTaskFromWaitQueue(taskID, sn); err != nil {
			Log("Info", err.Error())
			return err
		}
	}else{
		if err := DelTaskFromLoadingQueue(taskID, sn); err != nil {
			Log("Info", err.Error())
			return err
		}
	}

	//移除未完成队列中的任务
	if err := DelTaskFromLoadQueue(taskID, sn); err != nil {
		Log("Info", "移除未完成队列中的任务失败：", err.Error())
		return err
	}

	//修改任务状态
	if err := UpdateQueueTaskStatus(taskID, sn, taskStatus); err != nil {
		Log("Info", "修改任务状态失败：", err.Error())
		return err
	}

	return nil
}

//任务通知数据
func TaskDealResultNoticeData(sn string, taskId int64, info string) (model.Response, error) {
	mid, getMidErr := GenMid(sn)
	if getMidErr != nil {
		Log("Info", "取Mid失败")
		return model.Response{}, getMidErr
	}
	var returnData interface{} = model.ResponseData{
		Sn:     sn,
		TaskID: taskId,
		Notice: info,
	}
	requestMsg := model.Response{
		Mid:   mid,
		Mtype: constvar.MTypeTaskDealNoticeRequest,
		Time:  time.Now().Unix(),
		Data:  &returnData,
	}
	return requestMsg, nil
}

//推送下载任务队列数据组装
func PushTaskQueueToRouterData(sn string) (model.Response, error) {
	//获取下载中任务队列
	tasks := []model.Task{}
	loadingTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskLoadIngSetKey
	laodTaskNum, loadingErr := storage.RedisZCard(loadingTaskQueueCacheKey)
	if loadingErr != nil || laodTaskNum >= 1 {
		tasks = nil
	}
	res, _ := GetTaskQueueInfoCache(loadingTaskQueueCacheKey, sn, 10)
	for _, task := range res {
		//设置任务期望状态
		taskStatus, _ := strconv.Atoi(task["status"].(string))
		exceptStatus := model.ExceptTaskLoad
		if taskStatus == model.TaskStatusPauseing {
			exceptStatus = model.ExceptTaskPause
		}
		taskIdInt64, _ := strconv.ParseInt(task["taskId"].(string), 10, 64)
		loadTask := model.Task{
			URL:    task["url"].(string),
			TaskID: taskIdInt64,
			Status: exceptStatus,
		}
		if taskStatus != model.TaskStatusDeleting {
			tasks = append(tasks, loadTask)
		}
	}
	//获取最新任务版本号
	taskVer, getErr := UpdateTaskVerCache(sn)
	if getErr != nil {
		taskVer = 1
	}

	mid, getMidErr := GenMid(sn)
	if getMidErr != nil {
		Log("Info", "取Mid失败")
		return model.Response{}, getMidErr
	}
	var returnData interface{} = model.ResponseData{
		TasksVer: taskVer,
		Tasks:    tasks,
	}
	requestMsg := model.Response{
		Mid:   mid,
		Mtype: constvar.MtypePushTaskTodDownloadRequest,
		Time:  time.Now().Unix(),
		Data:  &returnData,
	}
	return requestMsg, nil
}

//组装 2.7	云端删除下载任务 数据
func DelTaskToRouterData(sn string, taskId int64, taskUrl string) (model.Response, error) {
	//获取最新任务版本号
	taskVer, getErr := UpdateTaskVerCache(sn)
	if getErr != nil {
		taskVer = 1
	}

	mid, getMidErr := GenMid(sn)
	if getMidErr != nil {
		Log("Info", "取Mid失败")
		return model.Response{}, getMidErr
	}

	var returnData interface{} = model.ResponseData{
		TasksVer: taskVer,
		TaskID:   taskId,
		TaskURL:  taskUrl,
	}

	requestMsg := model.Response{
		Mid:   mid,
		Mtype: constvar.MtypeDelTaskTodDownloadRequest,
		Time:  time.Now().Unix(),
		Data:  &returnData,
	}
	return requestMsg, nil
}

//获取接口参数mid,redis缓存自增
func GenMid(sn string) (int, error) {
	cacheKey := constvar.RouterMqRedisPrefix + sn + constvar.RedisWsMidFix
	todayStr := time.Now().Format("20060102")
	cacheExist := storage.RedisExists(cacheKey)
	if cacheExist == false {
		expire, err := e.GetNowToNextDayUnix()
		if err != nil {
			return 0, err
		}
		result, setErr := storage.RedisSet(cacheKey, 1, int(expire))
		if result {
			Log("Info", "设置Redis失败", "GenMid")
			return 0, setErr
		}
		midInt, _ := strconv.Atoi(todayStr + strconv.Itoa(1))
		return midInt, nil

	} else {
		value, incErr := storage.RedisIncr(cacheKey)
		if incErr != nil {
			Log("Info", "获取Mid号失败", "GenMid")
			return 0, incErr
		}
		midInt, _ := strconv.Atoi(todayStr + strconv.Itoa(value))
		return midInt, nil
	}

}

//AddTaskToLoadQueue 增加任务到未完成的队列（包含下载中，暂停，等待的任务）
func AddTaskToLoadQueue(taskID int64, sn string) error {
	loadTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskGoingSetKey
	_, err := storage.RedisZAdd(loadTaskQueueCacheKey, strconv.FormatInt(taskID, 10), taskID)
	if err != nil {
		Log("Info", "添加下载任务至未完成队列失败")
		return err
	}

	return nil
}

//DelTaskFromLoadQueue 删除未完成任务队列的任务
func DelTaskFromLoadQueue(taskID int64, sn string) error {
	taskIDStr := strconv.FormatInt(taskID, 10)
	loadTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskGoingSetKey
	_, delErr := storage.RedisZRem(loadTaskQueueCacheKey, taskIDStr)
	if delErr != nil {
		Log("Info", "删除未完成的队列任务失败")
		return delErr
	}

	return nil
}

//AddTaskToLoadingQueue 增加任务到下载中的队列(立即下载)
func AddTaskToLoadingQueue(taskID int64, sn string) error {
	loadingTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskLoadIngSetKey
	_, err := storage.RedisZAdd(loadingTaskQueueCacheKey, strconv.FormatInt(taskID, 10), taskID)
	if err != nil {
		Log("Info", "添加下载任务至立即下载队列失败")
		return err
	}
	if err := UpdateQueueTaskStatus(taskID, sn, model.TaskStatusCreating); err != nil {
		return err
	}

	return nil
}

//DelTaskFromLoadingQueue 移除下载中的队列任务
func DelTaskFromLoadingQueue(taskID int64, sn string) error {
	taskIdStr := strconv.FormatInt(taskID, 10)
	loadingTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskLoadIngSetKey

	if ok,_ := storage.RedisZIsMember(loadingTaskQueueCacheKey , strconv.FormatInt(taskID,10)  );!ok{
		return nil
	}
	_, delErr := storage.RedisZRem(loadingTaskQueueCacheKey, taskIdStr)
	if delErr != nil {
		Log("Info", "删除下载中的队列任务失败")
		return delErr
	}

	return nil
}

//AddTaskToWaitQueue 增加任务到等待中的队列
func AddTaskToWaitQueue(taskID int64, sn string) error {
	TaskWaitCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskWaitingSetKey
	_, err := storage.RedisRPush(TaskWaitCacheKey, taskID)
	if err != nil {
		Log("Info", "添加下载任务至等待中的队列失败")
		return err
	}
	if err := UpdateQueueTaskStatus(taskID, sn, model.TaskStatusWaiting); err != nil {
		return err
	}
	return nil
}

//DelTaskFromWaitQueue 删除等待中的队列任务
func DelTaskFromWaitQueue(taskID int64, sn string) error {
	TaskWaitCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskWaitingSetKey
	_, delErr := storage.RedisLRem(TaskWaitCacheKey, 1, taskID)
	if delErr != nil {
		Log("Info", "删除等待中的队列任务失败")
		return delErr
	}

	return nil
}

func GetWaitTaskNum(sn string) (int, error) {
	TaskWaitCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskWaitingSetKey
	if storage.RedisExists(TaskWaitCacheKey) == false {
		return 0, nil
	}
	return storage.RedisLLen(TaskWaitCacheKey)
}

//UpdateQueueTaskStatus 修改缓存任务状态
func UpdateQueueTaskStatus(taskID int64, sn string, status int) error {
	cacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskInfoKey + ":" + strconv.FormatInt(taskID, 10)
	data := map[string]interface{}{
		"status": status,
	}
	_, setErr := storage.RedisHSet(cacheKey, data, -1)
	if setErr != nil {
		Log("Info", "任务状态修改失败")
		return setErr
	}
	return nil
}

//UpdateTaskVerCache 修改任务版本号
func UpdateTaskVerCache(sn string) (int, error) {
	cacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskVerKey
	cacheExist := storage.RedisExists(cacheKey)
	if cacheExist == false {
		_, setErr := storage.RedisSet(cacheKey, 1, -1)
		return 1, setErr
	} else {
		value, incErr := storage.RedisIncr(cacheKey)
		if incErr != nil {
			Log("Info", "任务版本号修改失败")
			return 0, incErr
		}
		return value, nil
	}
}

//获取正在下载的任务列表
func GetLoadingTask(sn string) (map[string]string, error) {
	loadingTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskLoadIngSetKey
	result, err := storage.RedisZRange(loadingTaskQueueCacheKey, 0, 20)
	if err != nil {
		return nil, err
	}
	tasksMap := make(map[string]string)
	for _, value := range result {
		tasksMap[value] = value
	}
	return tasksMap, nil
}

//获取未完成的任务列表
func GetLoadTask(sn string) (map[string]string, error) {
	loadTaskQueueCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskGoingSetKey
	result, err := storage.RedisZRange(loadTaskQueueCacheKey, 0, 100)
	if err != nil {
		return nil, err
	}
	tasksMap := make(map[string]string)
	for _, value := range result {
		tasksMap[value] = value
	}
	return tasksMap, nil
}

//获取任务详情
func GetTaskQueueInfoCache(key string, sn string, count int) ([]map[string]interface{}, error) {
	result, err := storage.RedisZRevRange(key, 0, count)
	if err != nil {
		return nil, err
	}
	var taskInfo []map[string]interface{}
	for _, value := range result {
		taskInfoCacheKey := constvar.RouterRedisPrefix + sn + storage.RedisRouterTaskInfoKey + ":" + value
		res, err := storage.RedisHGetAll(taskInfoCacheKey)
		if err != nil {
			Log("Info", "任务获取详情失败")
		}
		taskInfo = append(taskInfo, res)
	}

	return taskInfo, nil
}
